#include "stdafx.h"

#include <math.h>

#include "orscuAlgIHSFusion.h"
#include "orscuAlgIHSFusion.cuh"

orsCuAlgIHSFusion::orsCuAlgIHSFusion()
{
	m_a0 = 0;
	m_a1 = 1;

	m_floatBufSize = 0;

	m_bBuf = NULL;
	m_gBuf = NULL;
	m_rBuf = NULL;

	m_panBuf = NULL;
}

orsCuAlgIHSFusion::~orsCuAlgIHSFusion()
{
	if( m_bBuf )
		delete m_bBuf;

	if( m_gBuf )
		delete m_gBuf;

	if( m_rBuf )
		delete m_rBuf;

	if( m_panBuf )
		delete m_panBuf;
}

void orsCuAlgIHSFusion::setStatistics( orsIAlgImageStatistics *panSta, orsIAlgImageStatistics *msSta, orsBandSet &msBandSet )
{
	//m_msBandSet = msBandSet;

	double msMean, msStdDev, panMean, panStdDev;

	panMean = panSta->getMean(0);	panStdDev = panSta->getStdDev(0);
	msMean = msSta->getMean(0);		msStdDev = msSta->getStdDev(0);

	m_a1 = msStdDev / panStdDev;
	m_a0 = msMean - m_a1*panMean;
}

void orsCuAlgIHSFusion::fusion( const orsIImageData *ms, const orsIImageData *pan, orsIImageData *fusionMS )
{
	// cuda divice initialize
	if ( !InitCUDA())
	{
		return;
	}
	int wid, hei;

	wid = ms->getWidth();
	hei = ms->getHeight();

	long floatBufsize = wid*hei;

	if( floatBufsize > m_floatBufSize )	{
		if( m_bBuf )	delete m_bBuf;
		if( m_gBuf )	delete m_gBuf;
		if( m_rBuf )	delete m_rBuf;
		if( m_panBuf )	delete m_panBuf;

		m_floatBufSize = floatBufsize;

		m_bBuf = (float *)new float[floatBufsize];
		m_gBuf = (float *)new float[floatBufsize];
		m_rBuf = (float *)new float[floatBufsize];
		m_panBuf = (float *)new float[ floatBufsize ];
	}
	
	//////////////////////////////////////////////////////////////////////////
	ms->buf2Float( 0, m_bBuf );
	ms->buf2Float( 1, m_gBuf );
	ms->buf2Float( 2, m_rBuf );

	pan->buf2Float( 0, m_panBuf );
	

////////////////////////////////////////////////////////////////////////// cuda malloc and memcpy

	int size = floatBufsize*sizeof(float);

	IHSFusion(m_bBuf, m_gBuf, m_rBuf, m_panBuf ,size, m_a1,m_a0, wid, hei);
	//////////////////////////////////////////////////////////////////////////

	fusionMS->bufFromFloat( 0, m_bBuf, 0, 1 );
	fusionMS->bufFromFloat( 1, m_gBuf, 0, 1 );
	fusionMS->bufFromFloat( 2, m_rBuf, 0, 1 );

}